package com.superhelper.processor.order.consumer;

import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Consumer;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.superhelper.common.Consts;
import com.superhelper.common.domain.DeliverRecord;
import com.superhelper.common.domain.DeliverRecordStatus;
import com.superhelper.common.domain.PushMsgType;
import com.superhelper.common.domain.TakeOutOrder;
import com.superhelper.common.domain.TakeOutOrderStatus;
import com.superhelper.common.domain.Task;
import com.superhelper.common.domain.dada.DaDaCallback;
import com.superhelper.common.mapper.DeliverRecordMapper;
import com.superhelper.common.mapper.TakeOutOrderMapper;
import com.superhelper.common.utils.JsonHelper;

@Component
public class DadaConsumer extends AbstractOrderConsumer implements ApplicationListener<ContextRefreshedEvent> {
    private static final Logger log = LoggerFactory.getLogger(DadaConsumer.class);

    private Consumer consumer;
    @Value("${aliyun.access.key}")
    private String aliyunAccessKey;
    @Value("${aliyun.access.secret}")
    private String aliyunSecretKey;

    @Value("${aliyun.dada.consumer.id}")
    private String consumerId;
    @Value("${order.topic}")
    private String topic;
    @Value("${online}")
    private boolean online;

    @Autowired
    private DeliverRecordMapper recordMapper;
    @Autowired
    private TakeOutOrderMapper orderMapper;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (event.getApplicationContext().getParent() != null) {
            return;
        }
        if (consumer != null) {
            return;
        }
        init();
        String tag = topic + online + "-dada";
        consumer.subscribe(topic, tag, new MessageListener() {
            public Action consume(Message message, ConsumeContext context) {
                try {
                    String content = new String(message.getBody(), Consts.UTF8_CHARSET);
                    log.info("content is:{}", content);
                    DaDaCallback cb = JsonHelper.fromJson(content, DaDaCallback.class);
                    if (cb == null) {
                        log.error("dadaConsumer entity is null");
                        return Action.CommitMessage;
                    }

                    try {
                        DeliverRecordStatus drs = DeliverRecordStatus.valueOf(cb.getOrder_status());
                        if (cb.getOrder_status() == DeliverRecordStatus.completed.getVal()) {
                            DeliverRecord dr = recordMapper.getById(NumberUtils.toLong(cb.getOrder_id()));
                            if (dr != null) {
                                recordMapper.updateStatusByStatusOrder(dr.getId(), cb.getOrder_status(), drs.getDesc(),
                                        cb.getDm_name(), cb.getDm_mobile());
                                orderMapper.updateSettledById(dr.getOrderId());
                            }

                        } else if (cb.getOrder_status() == DeliverRecordStatus.picking.getVal()) {
                            recordMapper.updatePickingById(NumberUtils.toLong(cb.getOrder_id()), drs.getDesc(),
                                    cb.getDm_name(), cb.getDm_mobile());
                        } else if (cb.getOrder_status() == DeliverRecordStatus.delivering.getVal()) {
                            DeliverRecord dr = recordMapper.getById(NumberUtils.toLong(cb.getOrder_id()));
                            if (dr != null) {
                                if (0 < recordMapper.updateStatusByStatusOrder(dr.getId(), cb.getOrder_status(),
                                        drs.getDesc(), cb.getDm_name(), cb.getDm_mobile())) {
                                    orderMapper.updateDeliveringById(dr.getOrderId());
                                }
                            }
                        } else {
                            String statusMsg = drs.getDesc();
                            if (drs == DeliverRecordStatus.canceled) {
                                statusMsg = cb.getCancel_reason();
                            }
                            // 如果取消原因是，配送员取消或者是系统取消，然后订单是有效状态，valid或者是delivering中，则重发快递单
                            if (StringUtils.equals(cb.getCancel_from(), "1")
                                    || StringUtils.equals(cb.getCancel_from(), "3")) {
                                DeliverRecord dr = recordMapper.getById(NumberUtils.toLong(cb.getOrder_id()));
                                if (dr != null) {
                                    TakeOutOrder order = orderMapper.getById(dr.getOrderId());
                                    if (order != null
                                            && (StringUtils.equalsIgnoreCase(order.getStatus(),
                                                    TakeOutOrderStatus.VALID.getValue()) || StringUtils
                                                    .equalsIgnoreCase(order.getStatus(),
                                                            TakeOutOrderStatus.DELIVERING.getValue()))) {
                                        dr.setExtId(dr.getExtId() + 1);
                                        dr.setId(null);
                                        dr.setStatus(DeliverRecordStatus.unsend.getVal());
                                        dr.setStatusMsg(null);
                                        dr.setDeliverNo(null);
                                        dr.setDeliverFee(0d);
                                        dr.setCurrentTip(0d);
                                        recordMapper.addDeliverRecord(dr);
                                        taskMapper.addTask(new Task(Consts.Task.deliver_record, dr.getId() + ""));
                                        log.info("resend deliver id:{}", dr.getId());
                                    }
                                }
                            }
                            recordMapper.updateStatusNotComplete(NumberUtils.toLong(cb.getOrder_id()),
                                    cb.getOrder_status(), statusMsg);
                            if (drs == DeliverRecordStatus.expired) {// 下发超时语音提示
                                DeliverRecord dr = recordMapper.getById(NumberUtils.toLong(cb.getOrder_id()));
                                TakeOutOrder order = orderMapper.getById(dr.getOrderId());
                                publish(order, PushMsgType.DELIVER_EXPIRE, false);
                            }
                        }
                    } catch (Throwable e) {
                        log.error("error", e);
                    }
                } catch (Exception e) {
                    log.error("DadaConsumer error", e);
                    return Action.ReconsumeLater;
                }
                return Action.CommitMessage;
            }

        });
        consumer.start();
        log.info("consumer started");

    }

    private void init() {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.ConsumerId, consumerId);
        properties.put(PropertyKeyConst.AccessKey, aliyunAccessKey);
        properties.put(PropertyKeyConst.SecretKey, aliyunSecretKey);
        consumer = ONSFactory.createConsumer(properties);
    }

}
